{% extends base %}
{% block head %}
<script type="text/javascript" src="/static/lib/utf.js"></script>
{% end %}
{% block body %}

<div class="card">
    {% set title = "16进制转换器" %}
    {% include "tools/base_title.html" %}

    <div class="col-md-6">
        <textarea id="input" class="col-md-12" rows=10 placeholder="输入"></textarea>
    </div>

    <div class="col-md-6">
        <textarea id="output" class="col-md-12" rows=10 placeholder="输出"></textarea>
    </div>

    <div class="col-md-12">
        <button onclick="hexToUtf8()">Hex->UTF8</button>
        <button onclick="utf8ToHex()">UTF8->Hex</button>
        <button onclick="numToHex()">Number->Hex</button>
        <button onclick="hexToNum()">Hex->Number</button>
    </div>

    <div id="error" class="col-md-12" style="color:red;">
    </div>

    <div class="col-md-12">
        <p>hex格式省略0x, 比如'hello'写成16进制为<code>68656c6c6f</code></p>
    </div>
</div>

<script>

var charCodeOfA = 'a'.charCodeAt(0);
var hexOffset = charCodeOfA - 10;

var HEX_TO_NUM_MAP = {
    "0":0, '1':1, '2':2, '3':3,
    '4':4, '5':5, '6':6, '7':7,
    '8':8, '9':9, '0':0,
    'a':10, 'b':11, 'c':12, 'd':13,
    'e':14, 'f':15,
    // 'A':10, 'B':11, 'C':12, 'D':13,
    // 'E':14, 'F':15
};

var NUM_TO_HEX_MAP = {};

for (var key in HEX_TO_NUM_MAP) {
    var value = HEX_TO_NUM_MAP[key];
    NUM_TO_HEX_MAP[value] = key;
}

function hexToDigit(c) {
    if (c >= 'a' && c <= 'f') {
        return c.charCodeAt(0) - hexOffset;
    } else if (c >= '0' && c <='9') {
        return c - '0';
    } else {
        throw "invalid hex char: " + c;
    }
}

function digitToHex(numVal) {
    return NUM_TO_HEX_MAP[numVal];
}

function byteToHex(byteVal) {
    return digitToHex(byteVal >> 4) + digitToHex(byteVal & 0xf);
}

function byteToHex2(byteVal) {
    return "\\x" + digitToHex(byteVal >> 4) + digitToHex(byteVal & 0xf);
}


function safeWrapper(func) {
    try {
        $("#error").text("");
        return func();
    } catch (e) {
        $("#error").text(e);
    } finally {
    
    }
}

function hexToAscii() {
    return safeWrapper(function () {
    var text = $("#input").val();
    var outstr = "";
    var byteArray = [];
    var charArray = [];
    for (var i = 0; i < text.length; i+=2) {
        var a = hexToDigit(text[i]);
        var b = hexToDigit(text[i+1]);
        var byteVal = (a << 4) + b;
        var charVal = String.fromCharCode(byteVal);
        // console.log(a,b,byteVal);
        byteArray.push(byteVal);
        charArray.push(charVal);
    }
    // TODO check utf-8
    $("#output").val(charArray.join(""));
});
}

function hexToUtf8() {
    return safeWrapper(function () {
    var text = $("#input").val();
    var outstr = "";
    var byteArray = [];
    var charArray = [];
    for (var i = 0; i < text.length; i+=2) {
        if (text[i]== '\\') {
            // 处理\x00这种形式的
            i += 2;
        }
        var a = hexToDigit(text[i]);
        var b = hexToDigit(text[i+1]);
        var byteVal = (a << 4) + b;
        charArray.push(String.fromCharCode(byteVal));
    }
    var utf8Value = charArray.join("");
    $("#output").val(utf8to16(utf8Value));
});
}

function strToHex() {
    return safeWrapper(function () {
        var text = $("#input").val();
        var outstr = "";
        var byteArray = [];
        for (var i = 0; i < text.length; i++) {
            var charCode = text.charCodeAt(i);
            if (charCode < 0xff) {
                byteArray.push(byteToHex(charCode));
            } else {
                // Unicode is build with a short value
                byteArray.push(byteToHex(charCode>>8));
                byteArray.push(byteToHex(charCode&0xff));
            }
        }
        // TODO check utf-8
        $("#output").val(byteArray.join(""));
    })
}

function numToHex() {
    return safeWrapper(function () {
        var text = $("#input").val();
        var numVal = parseInt(text);
        var hexStr = "";
        while (numVal > 0) {
            var byteVal = numVal & 0xf;
            numVal = numVal >> 4;
            hexStr = digitToHex(byteVal) + hexStr;
        }
        $("#output").val(hexStr);
    });
}

function hexToNum() {
    return safeWrapper(function () {
        var text = $("#input").val();
        var numVal = 0;
        for (var i = 0; i < text.length; i++) {
            var c = text[i];
            var decimal = hexToDigit(c);
            numVal = numVal * 16 + decimal;
        }
        $("#output").val(numVal);
    });
}

function utf8ToHex() {
    return safeWrapper(function () {
        var text = $("#input").val();
        text = utf16to8(text);
        var outstr = "";
        var byteArray = [];
        for (var i = 0; i < text.length; i++) {
            var charCode = text.charCodeAt(i);
            if (charCode < 0xff) {
                byteArray.push(byteToHex(charCode));
            } else {
                // Unicode is build with a short value
                byteArray.push(byteToHex(charCode>>8));
                byteArray.push(byteToHex(charCode&0xff));
            }
        }
        // TODO check utf-8
        $("#output").val(byteArray.join(""));
    })
}
</script>
{% end %}